#include "ObjectPath.h"

ObjectPath::ObjectPath(const string &s)
{
    vector<string> ids = split<string>(s, ".");
    foreach(const string &id, ids)
    {
        push_back(ObjectId(QString::fromStdString(id).toUInt()));
    }
}

ObjectPath::ObjectPath(const ObjectId &id)
: vector<ObjectId>(1, id)
{
}

ObjectPath::ObjectPath(const_iterator it1, const_iterator it2)
: vector<ObjectId>(it1, it2)
{
}

bool
ObjectPath::startsWith(const ObjectPath &prefix) const
{
    if (prefix.size() <= size()) {
        return std::equal(prefix.begin(), prefix.end(), begin());
    }
    return false;
}

bool
ObjectPath::endsWith(const ObjectPath &postfix) const
{
    if (postfix.size() <= size()) {
        return std::equal(postfix.begin(), postfix.end(), begin() + size() - postfix.size());
    }
    return false;
}

ObjectPath
ObjectPath::operator +(const ObjectId &id) const
{
    ObjectPath result(*this);
    result.push_back(id);
    return result;
}

ObjectPath
ObjectPath::operator +(const ObjectPath &other) const
{
    ObjectPath result(*this);
    result.insert(result.end(), other.begin(), other.end());
    return result;
}
ObjectPath &
ObjectPath::operator +=(const ObjectId &id)
{
    push_back(id);
    return *this;
}

ObjectPath &
ObjectPath::operator +=(const ObjectPath &other)
{
    insert(end(), other.begin(), other.end());
    return *this;
}

string
ObjectPath::toString() const
{
    string result;
    for (size_t i = 0; i < size(); ++i) {
        result += std::to_string(operator[](i)) + '.';
    }
    if (!result.empty()) {
        result.resize(result.size() - 1);
    }
    return result;
}

ObjectPath
ObjectPath::slice(int start, int end) const
{

    int len = size();
    if (start < 0) start = len + start;
    start = std::max(0, std::min(len, start));
    if (end < 0) end = len + end;
    end = std::min(len, end);
    if (start < end) {
        return ObjectPath(begin() + start, begin() + end);
    }
    return ObjectPath();
}
